package com.nulldev.util.other;

import com.nulldev.util.threading.v3.RunnableWorker;
import com.nulldev.util.threading.v3.ThreadDispatcher;

public abstract class CachedItem<T> {

	private T cachedItem;
	private final long expiry;
	
	public CachedItem(final long expiry) {
		this.expiry = expiry;
		ThreadDispatcher.instance().addTask(RunnableWorker.fromRunnable(new Runnable() {
			
			@Override
			public void run() {
				while (true) {
					try {
						CachedItem.this.cachedItem = null;
						CachedItem.this.cachedItem = CachedItem.this.accquire();
						Thread.sleep(CachedItem.this.expiry);
					}catch (Exception e) {
						e.printStackTrace();
						try {
							Thread.sleep(5 * 1000L);
						} catch (InterruptedException e1) {
						}
					}
				}
			}
		}, "$CachedItem." + CachedItem.this.hashCode()));
	}
	
	public abstract T accquire() throws Exception;
	
	public long expiry() {
		return this.expiry;
	}
	
	public T get() {
		return this.cachedItem;
	}
	
	public T getAuto() throws Exception {
		if (!this.hasCachedItem()) {
			this.cachedItem = this.accquire();
		}
		return this.cachedItem;
	}
	
	public boolean hasCachedItem() {
		return this.cachedItem != null;
	}
}
